package com.renbang.service.log;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.renbang.model.sys.SysLog;
import com.renbang.model.sys.SysUser;
import com.renbang.service.sys.SysLogServiceImp;

@Aspect
public class LogAspect {

	@Autowired
	private SysLogServiceImp logService;

	/**
	 * 添加业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.renbang.dao.*.*.insert(..))")
	public void insertCell() {
		System.out.println("=========================================");
	}

	/**
	 * 修改业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.renbang.dao.*.*.update(..))")
	public void updateCell() {
		System.out.println("=========================================");
	}

	/**
	 * 删除业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.renbang.dao.*.*.deleteById(..))")
	public void deleteCell() {
		System.out.println("=========================================");
	}
	
	/**
	 * 批量删除业务逻辑方法切入点
	 */
	@Pointcut("execution(* com.renbang.dao.*.deleteByIds(..))")
	public void deletesCell() {
		System.out.println("=========================================");
	}

	/**
	 * 添加操作(后置通知)
	 * 
	 * @param joinPoint
	 * @param rtv
	 */
	@AfterReturning(value = "insertCell()", argNames = "rtv", returning = "rtv")
	public void insertLog(JoinPoint joinPoint, Object rtv) throws Throwable {
		doLog(joinPoint);
	}

	/**
	 * 修改操作(后置通知)
	 * @param joinPoint
	 * @param rtv
	 * @throws Throwable
	 */
	@AfterReturning(value = "updateCell()", argNames = "rtv", returning = "rtv")
	public void updateLog(JoinPoint joinPoint, Object rtv) throws Throwable {
		doLog(joinPoint);
	}

	/**
	 * 删除操作
	 * 
	 * @param joinPoint
	 * @param rtv
	 */
	@AfterReturning(value = "deleteCell()", argNames = "rtv", returning = "rtv")
	public void deleteLog(JoinPoint joinPoint, Object rtv) throws Throwable {
		doLog(joinPoint);
	}

	/**
	 * 批量删除操作
	 * 
	 * @param joinPoint
	 * @param rtv
	 */
	@AfterReturning(value = "deletesCell()", argNames = "rtv", returning = "rtv")
	public void deletesLog(JoinPoint joinPoint, Object rtv) throws Throwable {
		doLog(joinPoint);
	}
	
	
	/**
	 * 使用Java反射来获取被拦截方法(insert、update)的参数值， 将参数值拼接为操作内容
	 * 
	 * @param args
	 * @param mName
	 * @return
	 */
	public String optionContent(Object[] args, String mName) {
		if (args == null) {
			return null;
		}
		StringBuffer rs = new StringBuffer();
		rs.append(mName);
		String className = null;
		// 遍历参数对象
		for (Object info : args) {
			// 获取对象类型
			className = info.getClass().getName();
			className = className.substring(className.lastIndexOf(".") + 1);
			rs.append(":"+info.toString()+" ");
		}
		return rs.toString();
	}
	
	public HttpServletRequest getRequest() {
		return ( (ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}
	
	

	private void doLog(JoinPoint joinPoint) {
		SysUser user=(SysUser) getRequest().getSession().getAttribute("user");
		if (user == null) {// 没有登录
			return;
		}
		// 判断参数
		if (joinPoint.getArgs() == null) {// 没有参数
			return;
		}
		// 获取方法名
		String methodName = joinPoint.getSignature().getName();
		// 获取操作内容
		SysLog log = new SysLog();
		System.out.println("=====================================================");
		String opContent = optionContent(joinPoint.getArgs(), methodName);
		log.setIp(getRequest().getRemoteAddr());
		log.setUserName(user.getUserName());
		log.setUserId(user.getUserId());
		log.setCreateTime(new Date());
		log.setLogContent(opContent);
		logService.add(log);
	}
}